home *** CD-ROM | disk | FTP | other *** search
- cseg segment
- org 100h
- assume cs:cseg, ds:cseg
- buffer equ 0B000h ;address of video buffer (presently monochrome)
- int_num equ 80h ;1st INT of consecutive series of five
- begin: jmp set_up
- tag1 db 'S T A',26,'C K '
- tag2 db ' VAR',26
- bottom db ' AX BX CX DX SI DI BP SP DS ES '
- msg db 'TURBOBUG loaded',0AH,0DH,'$'
-
- ;---NOTE: no provision for retrace synchronization -- causes a blizzard on CGA
-
- ;---ROUTINE THAT DRAWS THE STACK BEGINS HERE:
- stack: sti ;enable interrupts
- pushf ;save flags
- push ds ;save all changed registers
- push es ;
- push di ;
- push si ;
- push ax ;
- push bx ;
- push cx ;
- push dx ;
- push cs ;to get at variables (above) place
- pop ds ; code segment value in DS
- mov ax,buffer ;point ES to video buffer
- mov es,ax ;
- cld ;set direction flag
- ;---DRAW "STACK" LABEL ON TOP LEFT OF SCREEN:
- mov ah,112 ;use reverse image
- lea si,tag1 ;point to the data string
- mov cx,5 ;extends over five rows
- mov di,0 ;ES:DI points to top left of screen
- L1: lodsb ;get a character
- stosw ;write it, with attribute
- lodsb ;get next character
- stosw ;write it to the right of the former
- add di,156 ;point to next row
- loop L1 ;repeat
- ;---WRITE OUT THE STACK CONTENTS AND HEX EQUIVALENTS:
- mov cx,78 ;78 columns available
- mov di,324 ;point to 3rd col from left on 3rd row
- push bp ;will use BP as stack pointer
- mov bp,0FFFFH ;point to top of stack
- L2: mov ah,112 ;drawn in reverse image
- mov al,[bp] ;get a byte from the stack
- dec bp ;point to byte below for next time
- stosw ;write the byte in reverse image
- sub ah,ah ;byte in AL, clear AH
- shl ax,1 ;move top half of byte into AH
- shl ax,1 ;
- shl ax,1 ;
- shl ax,1 ;
- shr al,1 ;move bottom half back to bottom of AL
- shr al,1 ;
- shr al,1 ;
- shr al,1 ;
- cmp al,9 ;low nibble first: is it a numeral?
- jb L3 ;if so, jump ahead
- add al,55 ;else is A - F, add 55 to get ASCII code
- jmp short L4 ;go write it
- L3: add al,48 ;add 48 to get ASCII code for numeral
- L4: mov es:[di+318],al ;write it
- cmp ah,9 ;high nibble next: is it a numeral?
- jb L5 ;repeat same process as above
- add ah,55 ;
- jmp short L6 ;
- L5: add ah,48 ;
- L6: mov es:[di+158],ah ;
- loop L2 ;
- pop bp ;restore BP
- ;---PLOT BP POSITION:
- mov ax,bp ;BP value to AX
- neg ax ;NEG gives distance from top of stack
- mov bh,0 ;BH=0 flags that no scale drawn to right of BP
- mov dl,100 ;divide distance by 100
- div dl ;
- cmp al,0 ;less than 100?
- ja L8 ;if not, no BP label is written
- cmp ah,78 ;less than or equal to 78? (available space)
- ja L8 ;if not, no label
- je L7 ;BP on last col, don't set flag for right scale
- mov bh,1 ;no jump, flag that chars later drawn to right
- ;---WRITE "BP" IF BP IS ON THE SCALE:
- L7: push ax ;save distance to BP
- shl ah,1 ;double it to calculate video buffer position
- inc ah ;plus two more, since offsets are from BP=0
- inc ah ;
- mov al,ah ;transfer value to AL
- sub ah,ah ;extend through AX
- mov di,ax ;add value to buffer pointer
- mov ah,112 ;use reverse image
- mov al,'B' ;prepare to write the 'B'
- stosw ;write it
- add di,158 ;shift to character cell below
- mov al,'P' ;prepare to write the 'P'
- stosw ;write it
- pop ax ;restore distance to BP
- ;---CALCULATE AND WRITE SCALE FROM LEFT UP TO BP:
- sub cx,cx ;clear cx for counter
- mov cl,ah ;distance to BP
- dec cl ;minus 1 = number of chars to write
- mov ax,cx ;copy in AX
- push ax ;use later to calc chars to right
- jmp short L9 ;go make the division
- ;---CASE WHERE BP IS OFF THE SCALE:
- L8: mov bh,0 ;flag that no chars to right
- mov cx,78 ;BP off scale, write 78 chars
- mov al,ah ;move to AL the distance to BP
- dec al ;minus 1 to adjust for offset from 0
- sub ah,ah ;extend through AX
- push ax ;pseudo-PUSH, since other cases use it
- ;---WRITE SCALE TO LEFT OF BP:
- L9: mov di,164 ;pointer to first char
- mov dl,10 ;will divide by 10 for top line of scale
- div dl ;now ten's place in AL, one's place in AH
- add ah,48 ;add 48 to get the ASCII char equivalent
- inc ah ;INC to compensate for first DEC below
- add al,48 ;add 48 to get ASCII char equivalent
- L10: dec ah ;in loop, decrement 1's place digit
- cmp ah,'0' ;gotten to 0?
- ja L12 ;if not, no 10's place printed, jump ahead
- jb L11 ;if below '0', reset to '9'
- mov es:[di-160],al ;1's place is '0', so print 10's place char
- dec al ;decrement tens counter
- cmp al,'0' ;below '0'yet?
- jae L12 ;if not, jump ahead
- mov al,'9' ;else, reset to '9'
- jmp short L12 ;jump ahead
- L11: mov ah,'9' ;this line used when 1's place is reset
- L12: mov es:[di],ah ;print 1's place digit
- inc di ;point 2 bytes ahead in the video buffer
- inc di ;
- loop L10 ;go do next char(s) of the scale
- ;---DRAW SCALE TO RIGHT OF BP (IF REQUIRED):
- pop ax ;number chars to left
- cmp bh,0 ;test flag whether any chars
- je L16 ;if not, jump ahead and quit
- mov cx,77 ;max number of chars to draw (78 - 1 for bp)
- sub cx,ax ;subtract number chars drawn on left
- add ax,5 ;adjust for extra chars on left
- shl ax,1 ;double the number for video buffer position
- mov di,156 ;start of line position in buffer
- add di,ax ;add the offset
- mov al,'1' ;start counting from 1
- mov ah,al ;ten's place also starts from 1
- L13: mov es:[di],al ;loop: write a 1's place character
- inc di ;point to next buffer position
- inc di ;
- cmp al,'0' ;test whether 1's place has gotten to 0
- jne L14 ;if not, jump ahead
- mov es:[di-162],ah ;if so, write a ten's place character
- inc ah ;inc ten's place counter
- L14: inc al ;inc one's place counter
- cmp al,':' ;test if one's place has surpassed '9'
- jb L15 ;if not, jump ahead
- mov al,'0' ;else, reset one's place counter to '0'
- L15: loop L13 ;go write next character(s)
- L16: pop dx ;done!
- pop cx ;
- pop bx ;
- pop ax ;
- pop si ;
- pop di ;
- pop es ;
- pop ds ;
- popf ;restore flags
- iret ;return from the DISPLAY STACK interrupt
-
- ;-------------------------Display Memory Variable---------------------------
-
- ;---ON ENTRY, bx HOLDS OFFSET FROM bp OF VAR ADDRESS ON STACK
- ;---THE CALLING CODE MUST SAVE PRIOR CONTENTS OF bx IF THEY ARE REQUIRED
- var: sti ;enable hardware interrupts
- pushf ;save flags
- push ds ;save all changed registers
- push es ;
- push ax ;
- push cx ;
- push di ;
- push si ;
- cld ;set direction flag
- ;---WRITE THE 'VAR' LABEL:
- push cs ;set DS to CS value...
- pop ds ;...in order to access TAG2
- mov ax,buffer ;point ES to monochrome buffer
- mov es,ax ;
- mov di,800 ;point to 6th row of screen
- lea si,tag2 ;DS:SI points to 'VAR' string
- mov cx,6 ;these are six characters
- mov ah,112 ;write them in reverse image
- B1: lodsb ;get a character
- stosw ;write it
- loop B1 ;go do next
- ;---NOW WRITE OUT THE MEMORY CONTENTS:
- mov cx,74 ;number of cols available on the line
- add bx,bp ;add BP value to the offset from BP
- mov ax,ss:[bx+2] ;get segment address of var
- mov ds,ax ;place in DS
- mov si,ss:[bx] ;place offset of var in SI
- mov ah,15 ;write in intensified attribute
- B2: lodsb ;get a char
- stosw ;write it, setting the new attribute
- loop B2 ;go do next char
- pop si ;done! restore changed registers
- pop di ;
- pop cx ;
- pop ax ;
- pop es ;
- pop ds ;
- popf ;restore flags
- iret ;return from the DISPLAY VARIABLE interrupt
-
- ;-------------------------Register Display Routine--------------------------
-
- ;---THIS PROCEDURE WRITES OUT AX CONTENTS AS CHARS AND IN HEX:
- hexwrite proc near
- push bx ;save changed registers
- push ds ;
- push ax ;point DS to BIOS data area
- mov ax,40h ;
- mov ds,ax ;
- pop ax ;
- mov bh,4 ;test if ctrl key down
- test ds:[17h],bh ;
- mov bx,ax ;copy input reg in case jump taken
- jnz C2 ;go make hex write if ctrl down
- cmp ah,es:[di-156] ;test if high char is same as before
- jne C2 ;if not, go write hex equivalent
- cmp ah,32 ;is it a space char?
- jne C1 ;if not, will definitely not write in hex, jump
- cmp es:[di-160],ah ;if spc, chk line above. Will be 32 if first
- je C2 ; call on cleared screen, else FF from scroll
- C1: add di,4 ;not writing in hex, set buffer pointer ahead
- jmp short C7 ;jump ahead
- ;---WRITE THE HIGH BYTE IN HEX:
- C2: shr ax,1 ;shift AH halfway down into AL
- shr ax,1 ;
- shr ax,1 ;
- shr ax,1 ;
- shr al,1 ;shift AL nibble rest of the way down
- shr al,1 ;
- shr al,1 ;
- shr al,1 ;now high nibble in AH, low nibble in AL
- cmp ah,9 ;is high nibble a numeral?
- ja C3 ;if not, jump ahead
- add ah,48 ;add 48 to make ASCII char
- jmp short C4 ;jump ahead
- C3: add ah,55 ;A - F, so add 55 to make ASCII char
- C4: cmp al,9 ;repeat process for low nibble
- ja C5 ; (not looped here and elsewhere
- add al,48 ; for the sake of speed)
- jmp short C6 ;
- C5: add al,55 ;
- C6: mov es:[di],ah ;write the high nibble
- inc di ;move video buffer pointer to next col
- inc di ;
- stosb ;write the low nibble
- inc di ;move pointer to next col
- ;---WRITE THE HIGH AND LOW CHARS IN REVERSE IMAGE:
- C7: mov ah,112 ;code for reverse image
- mov al,bh ;get copy of high char
- stosw ;write it
- mov al,bl ;get copy of low char
- stosw ;write it
- ;---WRITE THE LOW BYTE IN HEX:
- mov bh,4 ;100B tests ctrl key
- test ds:[17h],bh ;chk BIOS variable whether ctrl key is down
- mov ah,bl ;copy of low byte to AH now, before jump taken
- jnz C9 ;if ctrl down, write the char in hex
- cmp ah,es:[di-162] ;test is char is the same as prior one
- jne C9 ;if not, write it in hex
- cmp ah,32 ;spc char is special case, since clears screen
- jne C8 ;if not spc, don't write hex equivalent
- cmp es:[di-160],ah ;if a spc, chk if it is one from CLRSCR
- je C9 ;if so, write out the hex code
- C8: add di,8 ;don't write hex, adjust buffer pointer
- jmp short C14 ;finished, go quit routine
- C9: shr ax,1 ;write out the two hex digits as above
- shr ax,1 ;
- shr ax,1 ;
- shr ax,1 ;
- shr al,1 ;
- shr al,1 ;
- shr al,1 ;
- shr al,1 ;
- cmp ah,9 ;
- ja C10 ;
- add ah,48 ;
- jmp short C11 ;
- C10: add ah,55 ;
- C11: cmp al,9 ;
- ja C12 ;
- add al,48 ;
- jmp short C13 ;
- C12: add al,55 ;
- C13: mov es:[di],ah ;
- inc di ;
- inc di ;
- stosb ;
- add di,5 ;forward buffer pointer to next register pos
- C14: pop ds ;restore changed registers
- pop bx ;
- ret ;quit
- hexwrite endp
-
- ;---THE REGISTER DISPLAY PROCEDURE STARTS HERE:
- regs: sti ;enable hardware interrupts
- pushf ;save flags
- cld ;set direction flag
- push ax ;these three re-restored at end
- push di ; since used in writing their own contents
- push es ;
- push es ;temporarily save ES and AX
- push ax ; while checking Alt key
- mov ax,40h ;point ES to BIOS data area
- mov es,ax ;
- mov ah,8 ;see if Alt key is down
- test es:[17h],ah ;
- pop ax ;restore ES and AX
- pop es ;
- jz D1 ;go ahead if Alt key not down
- jmp D5 ;else, quit the routine
- D1: push es ;push altered registers onto stack
- push ds ; in the left-right order in which they
- push di ; are displayed
- push si ;
- push cx ;
- push bx ;
- push ax ;
- mov ax,buffer ;now point ES to the video buffer
- mov es,ax ;
- push cs ;set DS to CS to get at bottom-of-screen labels
- pop ds ;
- ;---WRITE LABELS ON BOTTOM OF SCREEN:
- mov di,3842 ;ES:DI points to buffer position
- lea si,bottom ;DS:SI points to data string
- mov cx,10 ;there are 10 labels
- mov ah,112 ;will draw in reverse image
- D2: lodsb ;get a byte
- stosw ;write it with attribute
- lodsb ;etc...
- stosw ;
- lodsb ;
- stosw ;
- lodsb ;
- stosw ;
- lodsb ;
- stosw ;
- lodsb ;
- stosw ;
- add di,4 ;forward pointer to next label
- loop D2 ;go write next label
- ;---SCROLL THE 8TH - 24TH ROWS UPWARDS 1 LINE:
- push es ;set DS to video buffer address
- pop ds ;
- mov di,960 ;di points to start of 7th row
- mov si,1120 ;si points to start of 8th row
- mov cx,1360 ;number of chars+attribute to transfer
- rep movsw ;make the transfer
- ;---CLEAR 24TH ROW:
- mov cx,80 ;chars to clear
- mov ax,07FFH ;use FF as the 'space' char, 7 as the attribute
- mov di,3680 ;DI points to start of the line
- rep stosw ;clear it
- ;---DISPLAY THE REGISTERS:
- mov di,3682 ;point DI to position of first register
- pop ax ;momentarily restore AX contents
- call hexwrite ;write AX
- pop bx ;restore BX contents
- mov ax,bx ;move copy to AX
- call hexwrite ;write BX
- pop cx ;restore CX contents
- mov ax,cx ;move copy to AX
- call hexwrite ;write CX
- mov ax,dx ;DX unchanged, copy to AX
- call hexwrite ;write DX
- pop si ;restore SI contents
- mov ax,si ;move copy to AX
- call hexwrite ;write SI
- pop ax ;DI in use, pop contents straight into AX
- call hexwrite ;write DI
- mov ax,bp ;BP unchanged, copy to AX
- call hexwrite ;write BP
- mov ax,sp ;SP unchanged
- call hexwrite ;write SP
- pop ds ;restore DS
- mov ax,ds ;move copy to AX
- call hexwrite ;write DS
- pop ax ;ES in use, pop contents straight into AX
- call hexwrite ;write ES
- ;---CHECK SHIFT KEYS:
- mov ax,40h ;point ES back to BIOS data area
- mov es,ax ;
- D3: mov ah,8 ;1000B tests Alt key
- test es:[17h],ah ;is Alt down?
- jnz D5 ;if so, quit the routine
- mov ax,0102h ;1B in AH, 10B in AL
- test es:[17h],ah ;test right shift
- jnz D5 ;no delay if right shift down
- test es:[17h],al ;test left shift
- jz D3 ;keep looping until shift or Alt key down
- mov al,es:[6Ch] ;left shift down, read BIOS time-of-day
- add al,4 ;wait 4/18ths sec (may change this value)
- D4: cmp es:[6Ch],al ;read new time-of-day -- ready?
- jne D4 ;keep looping until ready
- D5: pop es ;done! restore registers used
- pop di ; to display the register values
- pop ax ;
- popf ;
- iret ;quit
-
- ;---------------------DRAW STACK PLUS REGISTERS---------------------------
- all: int int_num ;call stack routine
- int int_num+2 ;call register routine
- iret ;done
-
- ;--------------------------SETUP CODE-------------------------------------
- finish equ $ ;mark end of code for int 27h below
- set_up: mov dx,offset stack ;point DX to start of STACK DISPLAY code
- mov al,int_num ;assign it to the base vector
- mov ah,25h ;DOS function to set interrupt vector
- int 21h ;set the vector
- mov dx,offset var ;point DX to start of DISPLAY VAR code
- mov al,int_num+1 ;assign it to the base vector + 1
- int 21h ;set the vector
- mov dx,offset regs ;point DX to start of REGISTER DISPLAY code
- mov al,int_num+2 ;assign it to the base vector + 2
- int 21h ;set the vector
- mov dx,offset all ;point DX to start of STACK PLUS REGS code
- mov al,int_num+3 ;assign it to the base vector + 3
- int 21h ;set the vector
- mov ah,9 ;DOS function to write string
- lea dx,msg ;DS:DX pts to load message
- int 21h ;write the message
- lea dx,finish ;point DX to end of all resident code
- int 27h ;exit, leaving all resident except setup code
- cseg ends
- end begin